<template>
  <div class="message-bubble mb-6" :class="{ 'user-message': message.role === 'user' }">
    <div class="flex items-start space-x-3">
      <!-- 头像 -->
      <div
        class="flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center text-white font-semibold"
        :class="message.role === 'user' ? 'bg-blue-500' : 'bg-purple-500'"
      >
        <Icon :name="message.role === 'user' ? 'user' : 'robot'" size="20" class="text-white" />
      </div>

      <!-- 消息内容 -->
      <div class="flex-1 min-w-0">
        <!-- 消息头部 -->
        <div class="flex items-center justify-between mb-2">
          <div class="flex items-center space-x-2">
            <span class="font-medium text-gray-900">
              {{ message.role === 'user' ? '我' : 'AI 助手' }}
            </span>
            <span class="text-sm text-gray-500">{{ formatTime(message.createTime) }}</span>
          </div>
        </div>

        <!-- 消息主体 -->
        <div class="message-body">
          <div class="markdown-renderer" v-html="renderedContent"></div>
        </div>

        <!-- 消息操作按钮 -->
        <div v-if="message.role === 'assistant'" class="message-actions">
          <button
            @click="copyContent"
            class="btn-text text-xs px-3 py-1.5 rounded-md hover:bg-gray-100 transition-colors"
          >
            <Icon name="copy" size="14" class="mr-1" />
            复制
          </button>

          <button
            @click="regenerateMessage"
            class="btn-text text-xs px-3 py-1.5 rounded-md hover:bg-gray-100 transition-colors"
          >
            <Icon name="refresh" size="14" class="mr-1" />
            重新生成
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import MarkdownIt from 'markdown-it'
import { computed } from 'vue'
import Icon from './icons/Icon.vue'

export default {
  name: 'MessageBubble',
  components: {
    Icon,
  },
  props: {
    message: {
      type: Object,
      required: true,
    },
  },
  emits: ['regenerate'],
  setup(props, { emit }) {
    // 创建 Markdown 渲染器
    const md = new MarkdownIt({
      html: true,
      linkify: true,
      typographer: true,
      highlight: function (str, lang) {
        if (lang && hljs.getLanguage(lang)) {
          try {
            return (
              '<pre class="hljs"><code>' +
              hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
              '</code></pre>'
            )
          } catch (__) {}
        }
        return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>'
      },
    })

    // 计算渲染后的内容
    const renderedContent = computed(() => {
      return md.render(props.message.content || '')
    })

    const formatTime = (time) => {
      if (!time) return ''
      const date = new Date(time)
      return date.toLocaleTimeString('zh-CN', {
        hour: '2-digit',
        minute: '2-digit',
      })
    }

    const copyContent = async () => {
      try {
        await navigator.clipboard.writeText(props.message.content)
        showSuccessMessage('已复制到剪贴板')
      } catch (err) {
        showErrorMessage('复制失败')
      }
    }

    const regenerateMessage = () => {
      emit('regenerate', props.message)
    }

    const showSuccessMessage = (message) => {
      if (window.$toast) {
        window.$toast.success(message)
      }
    }

    const showErrorMessage = (message) => {
      if (window.$toast) {
        window.$toast.error(message)
      }
    }

    return {
      renderedContent,
      formatTime,
      copyContent,
      regenerateMessage,
      showSuccessMessage,
      showErrorMessage,
    }
  },
}
</script>

<style scoped>
.message-bubble {
  animation: fadeIn 0.3s ease-in-out;
}

.user-message {
  flex-direction: row-reverse;
}

.user-message .flex {
  flex-direction: row-reverse;
}

.user-message .flex > div:first-child {
  margin-right: 0;
  margin-left: 0.75rem;
}

.message-body {
  background: #f8fafc;
  border-radius: 0.75rem;
  padding: 1rem;
  margin-bottom: 0.5rem;
}

.user-message .message-body {
  background: #3b82f6;
  color: white;
}

.message-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

/* Markdown 渲染样式 */
.markdown-renderer {
  line-height: 1.6;
  color: #333;
}

.markdown-renderer :deep(h1),
.markdown-renderer :deep(h2),
.markdown-renderer :deep(h3),
.markdown-renderer :deep(h4),
.markdown-renderer :deep(h5),
.markdown-renderer :deep(h6) {
  margin-top: 24px;
  margin-bottom: 16px;
  font-weight: 600;
  line-height: 1.25;
}

.markdown-renderer :deep(h1) {
  font-size: 2em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 10px;
}

.markdown-renderer :deep(h2) {
  font-size: 1.5em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 8px;
}

.markdown-renderer :deep(p) {
  margin-bottom: 16px;
}

.markdown-renderer :deep(ul),
.markdown-renderer :deep(ol) {
  padding-left: 30px;
  margin-bottom: 16px;
}

.markdown-renderer :deep(li) {
  margin-bottom: 4px;
}

.markdown-renderer :deep(blockquote) {
  padding: 0 16px;
  margin: 16px 0;
  color: #6a737d;
  border-left: 4px solid #dfe2e5;
}

.markdown-renderer :deep(code) {
  padding: 2px 4px;
  font-size: 85%;
  background-color: rgba(27, 31, 35, 0.05);
  border-radius: 3px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}

.markdown-renderer :deep(pre) {
  padding: 16px;
  overflow: auto;
  font-size: 85%;
  line-height: 1.45;
  background-color: #f6f8fa;
  border-radius: 6px;
  margin-bottom: 16px;
}

.markdown-renderer :deep(pre code) {
  padding: 0;
  background-color: transparent;
  border-radius: 0;
}

.markdown-renderer :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin-bottom: 16px;
}

.markdown-renderer :deep(table th),
.markdown-renderer :deep(table td) {
  padding: 8px 12px;
  border: 1px solid #dfe2e5;
}

.markdown-renderer :deep(table th) {
  background-color: #f6f8fa;
  font-weight: 600;
}

.markdown-renderer :deep(a) {
  color: #0366d6;
  text-decoration: none;
}

.markdown-renderer :deep(a:hover) {
  text-decoration: underline;
}

.markdown-renderer :deep(img) {
  max-width: 100%;
  height: auto;
  border-radius: 6px;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
